Ich bin gespannt, warum die Rücktaste erforderlich ist, wenn IFS so eingestellt wird, dass Zeilenumbrüche wie folgt aufgeteilt werden:
IFS=$(echo -en "\n\b")
Warum kann ich das nicht einfach verwenden (was nicht funktioniert)?
IFS=$(echo -en "\n")
Ich bin auf einem Linux-System, das Dateien mit Unix-Zeilenenden speichert. Ich habe meine Datei mit Zeilenumbrüchen in Hex konvertiert und sie verwendet definitiv nur "0a" als Zeilenumbruchzeichen.
Ich habe viel gegoogelt und obwohl viele Seiten den Zeilenumbruch gefolgt von der Rücktaste dokumentieren, erklärt keine, die ich gefunden habe, warum die Rücktaste erforderlich ist.
-David.
for file in $(ls) ; do echo "$f" ; done
. B. in . Ohne das IFS nur auf Zeilenumbrüche zu setzen, gibt die for-Schleife jedes durch Leerzeichen getrennte Stück in jedem Dateinamen einzeln anstelle des gesamten Dateinamens wieder.Antworten:
Denn wie im Bash-Handbuch zur Befehlsersetzung steht :
Durch Hinzufügen
\b
verhindern Sie also das Entfernen von\n
.Ein sauberer Weg, dies zu tun, könnte darin bestehen,
$''
Zitate wie folgt zu verwenden :IFS=$'\n'
quelle
$'...'
ist für die Aufnahme in POSIX vorgesehen. [ mywiki.wooledge.org/Bashism] [ austingroupbugs.net/view.php?id=249]host=$(mysql -S $socket $catalog --skip-column-names -e "select host from mysql.user); echo "Host: $host"; IFS=$'\n';read -ra hostArray <<< "$host"; echo "HostArray:$hostArray" #This prints only 1 item. But there are 4 items;
Was ist hier falsch?Ich erinnerte mich nur an den einfachsten Weg. Getestet mit Bash auf Debian Keuchen.
IFS=" "
Im Ernst :)
quelle
Es ist ein Hack wegen der Verwendung
echo
und Befehlsersetzung.prompt> x=$(echo -en "\n") prompt> echo ${#x} 0 prompt> x=$(echo -en "\n\b") prompt> echo ${#x} 2
Die
$()
Streifen folgen nachgestellten Zeilenumbrüchen und\b
verhindern,\n
dass es sich um nachgestellte Zeilenumbrüche handelt, während es höchst unwahrscheinlich ist, dass sie in einem Text erscheinen.IFS=$'\n'
ist der bessere Weg, um IFS so einzustellen, dass es in Zeilenumbrüchen aufgeteilt wird.quelle
\n\b
Formation auch die Rücktaste alsIFS
Trennzeichen enthält, sodass ich dies unter bestimmten Umständen als fehlerhaft betrachten würde.\b
char als Suffix von newline\n
wird hinzugefügt, da das Ende\n
der Befehlssubstitution entfernt wurde,$(...)
sodass das\b
als Suffix für verwendet wird\n
und dadurch\n
nicht mehr nachgestellt wird, sodass es von der Befehlssubstitution zurückgegeben wird.Der Nebeneffekt, der darin besteht, dass
IFS
neben diesem auch ein\b
Zeichen und ein Trennzeichen vorhanden sind\n
, ist das alleinige Interesse.Wenn Sie erwarten, dass
\b
eines Tages in der Zeichenfolge etwas passiert (warum nicht?), Können Sie Folgendes verwenden:IFS="$(printf '\nx')" && IFS="${IFS%x}";
Das
returns \n suffixed with x
&&
removes x
Jetzt hat IFS nur noch das
\n
Zeichen.IFS="$(printf '\nx')" && IFS="${IFS%x}"; echo ${#IFS}; # 1
und nichts wird im Falle von
\b
Test brechen :#!/bin/sh sentence=$(printf "Foo\nBar\tBaz Maz\bTaz"); IFS="$(printf '\nx')" && IFS="${IFS%x}"; for entry in $sentence do printf "Entry: ${entry}.\n"; done
gibt zwei Zeilen (wegen einer
\n
):wie erwartet.
anstatt zu
IFS="$(printf '\nx')" && IFS="${IFS%x}";
verwenden:IFS=" "
gibt das gleiche Ergebnis, aber diese beiden Zeilen dürfen nicht eingerückt werden. Wenn Sie versehentlich Leerzeichen oder Tabulatoren oder andere weiße Zeichen zwischen "und" setzen, haben Sie dort nicht mehr nur
\n
Zeichen, sondern auch einige "Boni". Das ist schwer zu tun Stelle, es sei denn, Sie verwenden die Option Alle Zeichen in Ihrem Editor anzeigen.quelle
Das Drücken der Eingabetaste ohne Zuweisung funktioniert ebenfalls. Obwohl es so aussieht, als hätte jemand einen Fehler gemacht und ist schwer zu verstehen.
IFS= #This is a line
quelle