2017-09-19 4 views
-2

Dans un répertoire, il y a plusieurs fichiers tels que:unix liste de concaténer des fichiers en ligne

file1 
file2 
file3 

Y at-il un moyen simple de concaténer ces fichiers pour obtenir une ligne (reliée par « OR ») dans bash comme suit:

file1 OR file2 OR file3

Ou dois-je écrire un script pour cela?

+2

Qu'est-ce que vous avez essayé et échoué? Post it même si c'était trivial – Inian

Répondre

1

Vous pouvez simplement le faire avec

printf '%s OR ' $(ls -1 *) | sed 's/OR $/''/'; echo -e '\n' 

ls -1 * est le répertoire.

+5

cela ne fonctionnera pas si le nom de fichier a des espaces – RomanPerekhrest

+0

Vous devriez éviter les noms de fichiers avec des espaces sur Linux, mais vous avez raison. Je suppose que les noms de fichiers OP sont sans espaces – Vinny

+2

Veuillez passer par ceci: [Pourquoi vous ne devriez pas analyser la sortie de 'ls'] (http://mywiki.wooledge.org/ParsingLs) – anubhava

1

Le moment à prendre en compte est qu'un nom de fichier puisse contenir un espace (s).
Utilisez les suivantes ls + awk solution:

ls -1 * | awk '{ r=(r)? r" OR "$0 : $0 }END{ print r }' 

solution pour les noms de fichiers avec saut de ligne (s):

echo -e $(ls -1b hello* | awk -v RS= '{gsub(/\n/," OR ",$0); gsub(/\\ /," ",$0); print $0}') 
  • -b - ls option pour imprimer Escapes de style C pour les caractères non graphiques
+1

[Pourquoi * pas * parse 'ls'?] (Https://unix.stackexchange.com/questions/128985/pourquoi-not-parse-ls) – anubhava

+0

@Kent, vous ne l'avez pas compris. Je n'ai pas dit que je vais gérer les espaces - j'ai dit que c'est un moment important. C'est pourquoi 'ls -1' a été utilisé – RomanPerekhrest

+0

@anubhava, avez-vous testé les noms de fichiers comme' hello \ name'? Aussi, lisez mon commentaire pour Kent – RomanPerekhrest

2

Vous pouvez utiliser cette fonction pour imprimer tous les noms de fichiers (y compris ceux avec l'espace, saut de ligne ou des caractères spéciaux) avec " OR " comme séparateur (en supposant que votre nom de fichier ne contient pas de code ASCII 4):

orfiles() { 
    local IFS=$'\4' 
    local out="$*" 
    echo "${out//$'\4'/ OR }" 
} 

donnons le nom comme:

orfiles * 

Comment ça marche:

  1. Nous avons mis IFS (séparateur de champ interne) en ASCII 4 localement dans la fonction
  2. Nous enregistrons sortie "$*" dans la variable locale out. Cela placera \4 après chaque nom de fichier dans la variable $out.
  3. Enfin, en utilisant la substitution de chaînes BASH, nous remplaçons globalement \4 par " OR " tout en imprimant la sortie de $out.

Dans les systèmes Unix IFS est seulement un séparateur de caractère donc il ne peut pas stocker la chaîne de caractères multi " OR " et nous devons le faire en 2 étapes comme indiqué ci-dessus.

+1

'++', meilleure réponse! serait sage de dire, pourquoi 'IFS' a été réglé et remplacé de cette façon. Raison étant 'bash' ne permet pas de multi-caractère' IFS' comme 'Awk' ou d'autres outils font – Inian

+1

Merci et très bon point @Inian. Ajouté ma réponse. – anubhava

+0

Pourquoi utiliser '\ 4' au lieu de NUL' \ 0'? –

0
ls -1|awk -v q='"' '{printf "%s%s", NR==1?"":" OR ", q $0 q}END{print ""}' 

le ls & manière awk de le faire, par exemple, que le nom de fichier contenant des espaces:

kent$ ls -1 
file1 
file2 
'file with OR and space' 

kent$ ls -1|awk -v q='"' '{printf "%s%s", NR==1?"":" OR ", q $0 q}END{print ""}' 
"file1" OR "file2" OR "file with OR and space" 
+0

Si vous analysez la sortie de ls, -Q mettra les noms de fichiers entre guillemets et donc ls -1Q donnera "fichier1" "fichier2" –

+0

merci! @RamanSailopal – Kent

0
$ for f in *; do printf '%s%s' "$s" "$f"; s=" OR "; done; printf '\n' 
file1 OR file2 OR file3