Я бы взглянуть на csvkit, предложенный @ Хайден-Шиффом
Если вы не» я хочу спуститься по этой дороге, вот что я придумал. Хотя есть несколько предостережений:
Update: Ваша правка показывает, что ваши входные файлы не всегда есть две колонки, и я не нашел способ сделать cut
возвращается пустая строка (но с новой строки) для работы старой версии.
Так что теперь я иду через линию АСВЕН по линии, захватывая значение (или пустую строку) во временный файл для каждого входного файла, а затем вставить их все вместе в конце:
#!/usr/bin/env bash
FILES="infile_??.csv"
FINAL="final_table.csv"
COLUMN="3"
# Delete ${FINAL} if it exists.
[[ -f "${FINAL}" ]] && rm ${FINAL}
TMPFILES=""
for f in ${FILES}; do
while IFS='' read -r line || [[ -n "$line" ]]; do
val=$(cut -f ${COLUMN} -d, -s <<< $line)
[[ -n "${val}" ]] && echo "${val}" || echo " "
done < "${f}" > "${f}.${COLUMN}.csv"
TMPFILES="${TMPFILES} ${f}.${COLUMN}.csv"
done
paste -d, ${TMPFILES} > ${FINAL}
rm ${TMPFILES}
Ниже моя оригинальная версия, которая предполагает, что все файлы действительно имеют по крайней мере столько столбцов, сколько вы хотите прочитать:
- Не доволен моим решением, потому что вы открываете тот же файл снова и снова для чтения и в то же время. Мне любопытно узнать о методе передачи вывода неизвестного количества процессов в виде разных входных потоков в один конечный процесс.
- В вашем описании вы хотите второй столбец, но вы используете опцию
--complement
, которая возвращает все, кроме второй колонки. Это немного сбивает меня с толку. Я игнорирую это и соглашаюсь с вашим описанием.
Так вот:
#!/usr/bin/env bash
FILES="infile_??.csv"
FINAL="final_table.csv"
COLUMN="2"
# Delete ${FINAL} if it exists.
[[ -f "${FINAL}" ]] && rm ${FINAL}
for f in $FILES; do
if [[ -f ${FINAL} ]]; then
# ${FINAL} already exists from an earlier iteration
# If you have "moreutils" installed, you can use sponge:
# cut -d',' -f 2 ${f} | paste -d',' ${FINAL} - | sponge ${FINAL}
# otherwise you can use "echo" in the way below:
echo "$(cut -d',' -f ${COLUMN} ${f} | paste -d',' ${FINAL} -)" > ${FINAL}
else
# ${FINAL} does not yet exist, we have to create it.
cut -d',' -f ${COLUMN} ${f} > ${FINAL}
fi
done
Обновление: Я понимаю, что он должен взять второй столбец каждого входного файла и записать их столбец после столбца в выходной файл, например:
Мои входные файлы:
infile_01.txt
:
111, 112, 113
121, 122, 123
131, 132, 133
141, 142, 143
4444516410617451515053 Не 691368888
infile_02.txt
:
211, 212, 213
221, 222, 223
231, 232, 233
241, 242, 243
(Таким образом, каждый номер 100 * (файл нет) + 10 * (строка нет) + (колонка нет).)
Мой код, на моем компьютере, производит этот вывод:
112, 212
122, 222
132, 232
142, 242
Если это то, что вы получите, но не то, что вы хотите, скажите мне, как выходной файл должен выглядеть с этими входными файлами. Если это не то, что вы получаете, запустите его в своей системе с моими файлами и скажите мне, что вы получаете.
Беспорядок в каком смысле? Почему вы используете '--complement', если хотите действительно получить второй столбец (а не все ** кроме ** второго столбца)? – chw21
Если вы работаете с файлами CSV, я настоятельно рекомендую csvkit - это набор инструментов CLI, которые упростят создание сценариев. –
Большое спасибо, ребята! chw21 Я попробую ваш код. Если я не использую дополнение, он объединит как столбец 1, так и столбец 2 и будет использовать его как столбец в объединенном файле :( – Emiliano