Z-оболочка

Z-оболочка

Я хочу вызвать команду для каждой строки стандартного ввода, как и xargs, но строка должна быть передана как стандартный ввод, а не как аргумент командной строки:

cat some-file.txt | <magic> | wc -c
  • это должно вывести количество символов в каждой строке файла.

Какие у меня есть варианты?

решение1

Как насчет простой петли?

while IFS= read -r line ;
do
   printf "%s" "$line" | wc -c
done < some-file.txt

решение2

Цикл while-read наиболее понятен. Если вы хотите использовать xargs, чтобы сделать что-то для каждой строки, вы можете получить чудовище вроде этого:

printf "%s\n" "foo bar" one " 1 2 3" | 
xargs -d '\n' -n 1 -I LINE bash -c 'wc -c <<< "LINE"'
8
4
7

Довольно затратно, так как для каждой строки приходится запускать процесс bash.

решение3

cat file.txt | while IFS= read -r i; do echo -n "$i" | wc -c; done
##  or (better):
while IFS= read -r i; do echo -n "$i" | wc -c; done < file.txt

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

##  Prints the contents of each line underneath the character count:
while IFS= read -r i; do echo -n "$i" | wc -c; echo "$i"; done < file.txt
##  Prints the line number alongside the character count:
n=0; while IFS= read -r i; do n=$((n+1)); echo -n "line number $n : "; echo -n "$i" | wc -c; done < file.txt

Для большей портативности вы можете использовать printf '%s' "$i"вместо всех echo -ns

решение4

Z-оболочка

Сохранения строк в переменной можно избежать, используя опцию-e

setopt pipefail
cat some-file.txt |
  
  while read -re | wc -c
  do
  done

-rчитает \s как есть

-eотображает ввод вместо того, чтобы присваивать его какой-либо переменной

pipefailделает read -re | wc -cвыход с ненулевым кодом статуса, как только so делает read -re, что он будет в конце файла

К сожалению, эта опция недоступна в Bash.

Связанный контент