Bash читает с разделителем после новой строки

Если вывод может быть смешанным (не сохранять исходный порядок строк), вы можете использовать join

join -o 2.1,1.2 -2 2 -t':' \
    <(sed 's/^/ /;s/ =/:/' File1 |sort -t: -k1,1)\
    <(sort -t: -k2 File2)
2
10.05.2016, 18:05
3 ответа

Для оболочки со встроенной командой read , которая может обрабатывать CSV, вы можете использовать ksh93 вместо bash :

$ while IFS='|' read -rS a b c; do printf '%s\n' "$b"; done < file
111
222
333

Чтобы преобразовать этот формат во что-нибудь что bash read может обработать, вы можете сделать:

< file ksh93 -c 'while IFS="|" read -rSA a; do
                   printf "%s|" "${a[@]//[\|]/\\\0}"
                   printf "\0"
                 done' |
       bash -c 'while IFS="|" read -d "" a b c; do
                  printf "%s\n" "$b"
                done'
4
27.01.2020, 21:56

Вам действительно стоит использовать правильный анализатор CSV. Например, используя тот, который поставляется с ruby:

ruby -rcsv -e 'CSV.foreach("file", :col_sep => "|") {|row| p row; puts row[1]}'

мы получаем

["aaa", "111", "!!!", ""]
111
["bbb", "222", "@@\n@", ""]
222
["ccc", "333", "###", ""]
333

Вы можете видеть для 2-й строки, есть встроенная новая строка. Удалите p row , чтобы избавиться от этих «отладочных» строк.

1
27.01.2020, 21:56

ОК, лучшим решением для меня (но, думаю, это дело вкуса) было использование fgetcsv от PHP, поскольку у меня уже есть PHP на этом сервере. Жаль, что команда bash read не обрабатывает новые строки так же хорошо, как функция PHP. Она автоматически распознает дополнительные разделители (например, "'s").

Образец:

<?php
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 10000, "|")) !== FALSE) {
        $num = count($data);
        echo "$num fields in line $row:\n";
        $row++;
        for ($c=0; $c < $num; $c++) {
            echo $c + 1 . ": " . $data[$c] . "\n";
        }
    }
    fclose($handle);
}
?>

Вывод (например, в моем исходном вопросе):

4 fields in line 1:
1: aaa
2: 111
3: !!!
4: 
4 fields in line 2:
1: bbb
2: 222
3: @@
@
4: 
4 fields in line 3:
1: ccc
2: 333
3: ###
4: 
0
27.01.2020, 21:56

Теги

Похожие вопросы