Bash - проблема с удалением строк, содержащих нулевые значения - PullRequest
0 голосов
/ 01 февраля 2020

У меня есть файл .csv, который необходимо изменить следующим образом: для каждого столбца в файле проверьте, содержит ли этот столбец пустые записи. Если это так, он удаляется из файла. В противном случае этот столбец остается. Я попытался решить эту проблему с помощью следующего сценария:

cp file-original.csv file-tmp.csv

for (( i=1;i<=65;i++)); do
  for var in $(cut -d, -f$i file-tmp.csv); do
    if [ -n $var ]; then
      continue
    else
      cut -d, --complement -f$i file-tmp.csv > file-tmp.csv
      break
    fi
  done
done

Я предполагаю, что проблема заключается в сохранении результата каждой итерации в файл, который также повторяется (file-tmp.csv). Однако я не уверен, как это обойти.

Ответы [ 3 ]

0 голосов
/ 01 февраля 2020
$ cat foo.csv
a,,c,d
a,b,,d

$ cat tst.awk
BEGIN { FS=OFS="," }
NR==FNR {
    for (inFldNr=1; inFldNr<=NF; inFldNr++) {
        if ($inFldNr ~ /^$/) {
            skip[inFldNr]
        }
    }
    next
}
FNR==1 {
    for (inFldNr=1; inFldNr<=NF; inFldNr++) {
        if ( !(inFldNr in skip) ) {
            out2in[++numOutFlds] = inFldNr
        }
    }
}
{
    for (outFldNr=1; outFldNr<=numOutFlds; outFldNr++) {
        inFldNr = out2in[outFldNr]
        printf "%s%s", $inFldNr, (outFldNr<numOutFlds ? OFS : ORS)
    }
}

$ awk -f tst.awk foo.csv foo.csv
a,d
a,d
0 голосов
/ 01 февраля 2020

Глядя на ваш вопрос, я нашел очень простой ответ, используя только команду grep и вывод во временный файл. Предположим, ваш CSV-файл называется test.csv. Далее создается файл test1.csv, в котором исключены все строки, содержащие значение null: опция

grep -v null test.csv > test1.csv

-v инвертирует вывод команды grep, повторяя строки, которые не содержат null внутри. Вывод может быть перенаправлен в другой файл, а затем вы можете заменить исходный файл test.csv.

0 голосов
/ 01 февраля 2020

Вы должны использовать временный файл, как в

cut -d, --complement -f$i file-tmp.csv > tmp.csv && mv tmp.csv file-tmp.csv

for var in $(cut -d, -f$i file-tmp.csv) глючит: вы не сможете обнаружить пустую строку, как эта, потому что разделение слов просто пропустит ее.

Во-первых, вы можете избежать всех копий файлов, отслеживая столбцы, которые хотите отбросить, а затем отбросить их все в одном go:

for i in {1..65}; do
    if grep -q '^$' <(cut -d, -f "$i" file-original.csv); then
        drop+=("$i")
    fi
done

cut -d, --complement -f "$(IFS=,; echo "${drop[*]}")" file-original.csv \
    > file-tmp.csv

. grep, чтобы увидеть, содержит ли столбец пустую строку, избегая медленной l oop и ошибки разделения слов.

После for для l oop массив drop содержит все номера столбцов, которые мы хотим отбрасывать, и $(IFS=,; echo "${drop[*]}") печатает их в виде списка через запятую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...