
Ich möchte für jede Zeile der Standardeingabe einen Befehl aufrufen, ähnlich wie xargs
, aber die Zeile sollte als Standardeingabe und nicht als Befehlszeilenargument übergeben werden:
cat some-file.txt | <magic> | wc -c
- Dadurch sollte die Anzahl der Zeichen in jeder Zeile der Datei gedruckt werden.
Welche Möglichkeiten habe ich?
Antwort1
Wie wäre es mit einer einfachen Schleife
while IFS= read -r line ;
do
printf "%s" "$line" | wc -c
done < some-file.txt
Antwort2
Eine while-read-Schleife ist am übersichtlichsten. Wenn Sie xargs verwenden möchten, um für jede Zeile etwas zu tun, könnte das Ergebnis ein Monstrum wie dieses sein:
printf "%s\n" "foo bar" one " 1 2 3" |
xargs -d '\n' -n 1 -I LINE bash -c 'wc -c <<< "LINE"'
8
4
7
Ziemlich teuer, da Sie für jede Zeile einen Bash-Prozess starten müssen.
Antwort3
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
Dies wird jedochNurDrucken Sie die Anzahl der Zeichen in einer Zeile, jeweils eine Zeile nach der anderen. Wenn Sie etwas Lesbareres möchten, benötigen Sie möglicherweise eine der folgenden Optionen:
## 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
Für eine bessere Portabilität können Sie printf '%s' "$i"
anstelle aller echo -n
s verwenden
Antwort4
Z-Schale
Das Speichern von Zeilen in einer Variablen kann durch die Option vermieden werden-e
setopt pipefail
cat some-file.txt |
while read -re | wc -c
do
done
-r
liest \
s wie sie sind
-e
gibt die Eingabe aus, anstatt sie einer Variablen zuzuweisen
pipefail
beendet read -re | wc -c
mit einem Statuscode ungleich Null, sobald dies der Fall ist read -re
, was am Ende der Datei der Fall sein wird.
Leider ist diese Option in Bash nicht verfügbar