Использовал эту комбинацию команд 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" Предполагая, что ваш 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
, которая делает то же самое.
С помощью awk
вы можете сделать такой системный вызов:
awk -F',' '{system("<command> "$1" "$2" "$3)}' file
Может потребоваться заключать в кавычки переменные, передаваемые оболочке, например. с фамилиями, состоящими из двух элементов, разделенных пробелом --, это также зависит от того, как ваша команда понимает элементы, разделенные пробелом -. В этом случае используйте:
awk -F',' '{system("<command> \""$1"\" \""$2"\" \""$3"\"")}'