Перебор столбцов

Использовал эту комбинацию команд find, xargs, ls, sed, wc и awk, и она работает:

find. -type f \( -iname "desktop.ini" -o -name "thumb.db" \)  -printf %h\\0 | xargs -0 -I "{}" sh -c 'printf "{}\t"; ls -l "{}" | sed -n "1!p" | wc -l' | awk '$2 == "1" {print $0}'

Пояснение:

  • find.найти в текущем каталоге
  • -type fнайти только файлы
  • \( -iname "desktop.ini" -o -name "thumb.db" \)где имя файла "desktop.ini" или "thumb.db" без учета регистра
  • printf %h\\0вывести начальный каталог имени файла + ASCII NUL
  • xargs -0 -I "{}" sh -c 'printf "{}\t"; ls -l "{}"распечатать выходной каталог и выполнить ls -lдля каждого из них
  • sed -n "1!p" | wc -l'исключить первую строку из ls -l, содержащую общее количество файлов и каталогов, а затем подсчитать строки
  • awk '$2 == "1" {print $0}'вывести строку, если только count равен "1"
2
13.10.2021, 10:38
2 ответа

Предполагая, что ваш CSV имеет формат «простой CSV», в котором ни одно поле не содержит встроенных запятых или новых строк (, которые разрешены в общих CSV-файлах, с полями в кавычках ), вы можете читать поля напрямую с помощьюread:

while IFS=, read -r name familyname address; do
    printf 'Got "%s", "%s", and "%s"\n' "$name" "$familyname" "$address"
done <file.csv

Утилита readразобьёт каждую строку на поля по значениям в $IFS, и мы убедимся, что эта переменная содержит запятую при вызове read. Первые два поля, разделенные запятой -, окажутся в переменных nameи familyname, а остальная часть строки окажется в переменной address. Если каждая строка заканчивается нежелательной запятой (, как в вопросе ), то прочитайте фиктивную переменную в каждой строке (, добавьте dummyпосле addressкак отдельную переменную с помощьюread)или отрегулируйте значение addressс address=${address%,}внутри цикла, чтобы отрезать замыкающую запятую.

Мы используем -rс readдля правильного чтения всех символов обратной косой черты в данных.

Если в CSV-файле есть строка заголовка, которую нужно пропустить,

sed 1d file.csv |
while IFS=, read -r name familyname address; do
    printf 'Got "%s", "%s", and "%s"\n' "$name" "$familyname" "$address"
done

Вместо команды sed(, которая удаляет первую строку ввода и передает все остальные строки на ), вы можете использовать tail -n +2, которая делает то же самое.

5
13.10.2021, 11:28

С помощью awkвы можете сделать такой системный вызов:

awk -F',' '{system("<command> "$1" "$2" "$3)}' file

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

awk -F',' '{system("<command> \""$1"\" \""$2"\" \""$3"\"")}'
2
13.10.2021, 12:56

Теги

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