2010-12-07 22 views
32

Ich habe jeden Tag eine automatisch generierte Datei, die von einem Shell-Skript aufgerufen wird. Aber das Problem ist, ich bin vor, dass die automatisch generierte Datei, die eine Form hat:SPRINTF in Shell-Skripten?

FILE_MM_DD.dat 

... wo MM und DD sind 2-stelligen Monat und Tag-of-the-Monats-Strings.

Ich habe ein paar Nachforschungen angestellt und habe es selbst geknackt, aber ich weiß nicht, wie ich diese benutzerdefinierten Zeichenfolgen nur mit Shell-Skripten erstellen kann.

Um klar zu sein, ich bin mir bewusst, der DATE-Funktion in Bash, aber was ich suche ist das Äquivalent der Funktion sprintf in C.

+0

Auch erfordern mein spec, dass ich Strings wie FILE_12_1.dat statt FILE_12_01.dat erzeugen, wo erforderlich. –

+0

Dann ist das "DD" falsch. –

+1

Korrekt, die DD ist nicht Teil meiner Spezifikation, sondern nur eine Abkürzung für die Erklärung der Dinge. Irgendwelche Ideen? –

Antwort

42

In Bash:

var=$(printf 'FILE=_%s_%s.dat' "$val1" "$val2") 

oder das Äquivalent, und näher an sprintf:

printf -v var 'FILE=_%s_%s.dat' "$val1" "$val2" 

Wenn Ihre Variablen Dezimalwerte mit führenden Nullen enthalten, können Sie die führenden Nullen entfernen :

val1=008; val2=02 
var=$(printf 'FILE=_%d_%d.dat' $((10#$val1)) $((10#$val2))) 

oder

printf -v var 'FILE=_%d_%d.dat' $((10#$val1)) $((10#$val2)) 

Die $((10#$val1)) nötigt den Wert in der Basis 10, so dass die %d in der Formatspezifikation glaubt nicht, dass „08“ ist ein ungültiger Oktalwert.

Wenn Sie date verwenden (zumindest für GNU date), können Sie die führenden Nullen wie folgt weglassen:

date '+FILE_%-m_%-d.dat' 

Für Vollständigkeit, wenn Sie wollen führende Nullen hinzufügen, um eine gepolsterte bestimmte Breite:

val1=8; val2=2 
printf -v var 'FILE=_%04d_%06d.dat' "$val1" "$val2" 

oder mit dynamischen Breiten:

val1=8; val2=2 
width1=4; width2=6 
printf -v var 'FILE=_%0*d_%0*d.dat' "$width1" "$val1" "$width2" "$val2" 

Das Hinzufügen führender Nullen ist nützlich, um Werte zu erstellen, die leicht sortiert und in Spalten ausgerichtet werden können.

+0

Danke Dennis. Dies ist die nächste Lösung, die ich bisher gesehen habe. Und am nächsten, ich meine perfekt :) –

+1

Zitate! '" $ var1 "', '" $ var2 "' usw. Selbst wenn man weiß, dass die Werte numerisch sind - was ist, wenn es Ziffern in IFS gibt? –

+1

@CharlesDuffy: Zitate hinzugefügt. Normalerweise habe ich eine Überwachungsfunktion, die feststellt, ob "IFS" Ziffern oder das Vorhandensein anderer unerwünschter Bedingungen enthält, und, wenn dies der Fall ist, "dd" Nullen für alle erreichbaren Dateisysteme. ;-) –

7

Warum nicht das printf-Programm von coreutils mit?

$ printf "FILE_%02d_%02d.dat" 1 2 
FILE_01_02.dat 
+1

Danke, Heiligenschein. Ich habe auch gerade diese Option gefunden: $ date "+ FILE_% m_% d" FILE_12_07 –

+0

Um klar zu sein, was ich möchte, ist eine Kürzung der führenden Nullen, aber ich denke, dass ich das aus dem PRINTF Mann herausfinden kann Seite. –

+0

Was meinst du mit "Abschneiden von führenden Nullen"? Bitte erkläre und biete meine Fähigkeiten bei printf oder regex magic an ;-) Wenn du die Lösung selbst findest, poste bitte. Ich wäre daran interessiert, zu verstehen, was Sie eigentlich brauchen. –

1

Versuchen:

sprintf() { local stdin; read -d '' -u 0 stdin; printf "[email protected]" "$stdin"; } 

Beispiel:

$ echo bar | sprintf "foo %s" 
foo bar