Ich habe eine Textdatei mit einem Dateinamen in jeder Zeile:
111_c4l5r120.png
123_c4l4r60.png
135_c4l4r180.png
147_c4l3r60.png
15_c4l1r120.png
...
Ich möchte es in diese Form umwandeln:
111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15
...
mit diesem Code:
#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
echo "$line" >> output.txt
echo "$line" | cut -d'_' -f 1 >> output.txt
done < "$1"
aber das Ergebnis ist:
111_c4l5r120.png
111
123_c4l4r60.png
123
135_c4l4r180.png
135
147_c4l3r60.png
147
15_c4l1r120.png
15
...
Wie soll ich mein Skript ändern, um die gewünschte Ausgabe zu erhalten?
shell
shell-script
Ali
quelle
quelle
Antworten:
Sofern Sie die Shell nicht speziell dafür benötigen, bietet die Antwort von terdon bessere Alternativen.
Da Sie
bash
(wie im Schebang des Skripts angegeben) verwenden, können Sie die-n
Option zum Echo verwenden:Oder Sie können Shell-Features verwenden, um die Zeile zu verarbeiten, ohne Folgendes zu verwenden
cut
:(beide
echo
Zeilen ersetzen ).Alternativ können
printf
Sie auch den Trick ausführen, in jeder POSIX-Shell arbeiten und im Allgemeinen besser sein (weitere Informationen finden Sie unter Warum ist printf besser als Echo? ):oder
(Streng genommen in Ebene
/bin/sh
,echo -n
nicht tragbar ist . Da Sie explizit mitbash
ihm ist OK hier.)quelle
Mach so etwas nicht in der Shell! Es ist weitaus komplexer als nötig, fehleranfällig und weitaus langsamer. Es gibt viele Tools, die für eine solche Textmanipulation entwickelt wurden. Zum Beispiel in
sed
(hier unter der Annahme der jüngsten GNU- oder BSD-Implementierungen für-E
):Oder für jeden
sed
:Perl:
awk:
quelle
sed
einesed 's/\([^_]*\).*/& \1/' file
für zusätzliche Portabilität machen. Ist, können Sie sich verlassenawk
undsed
ist es mehr , als man auf so ziemlich alles andere zählen.Hier sind Sie ja:
Ausgabe:
quelle