Question AWK et noms de fichiers avec espace.


J'essaie d'analyser les fichiers avec awk pour changer leurs noms. Tout s'est bien passé jusqu'à ce que je commence à le faire avec des fichiers avec un espace dans le nom du fichier. Les noms de fichiers sont quelque chose comme 11237_712312955_2012-01-04 18_31_03.wav et je veux remplacer wav du nom du fichier. Voici un exemple de mon code:

ls | awk -F\. '{print $1}'

Après avoir exécuté ceci dans la console, tout est en ordre et je reçois le nom du fichier sans extension.

Exemple: fichier 11237_712312955_2012-01-04 18_31_03.wav

après ls | awk -F\. '{print $1}' en console je me fais:

11237_712312955_2012-01-04 18_31_03 et c'est correct.

Mais quand je mets ceci dans mon script:


#!/bin/bash
for i in $(ls);
do
  FILENAME=echo $i | awk -F\. '{print $1}'; #problematic line 
  echo $FILENAME
done


4
2018-04-02 09:19


origine


Renommez vos fichiers pour supprimer les espaces. Sérieusement. Les espaces ne font pas plus partie des noms de fichiers que les tatouages ​​dans le bas du dos. - Tom O'Connor
Ouais je le sais. J'ai supprimé les espaces après avoir reconnu et renommé des fichiers. - B14D3


Réponses:


Le problème ici est l'analyse avec ls. Pensez à jeter un coup d'oeil ici: Pourquoi vous ne devriez pas analyser la sortie de ls.

La raison pour laquelle vous ne devriez pas le faire est qu’UNIX autorise presque tous les caractères d’un nom de fichier, y compris les espaces, les nouvelles lignes, les virgules, les symboles de conduite et pratiquement tout ce que vous essayez d’utiliser comme délimiteur, à l’exception de NUL. Dans son mode par défaut, si la sortie standard n’est pas un terminal, ls sépare les noms de fichiers avec des nouvelles lignes. C'est bien jusqu'à ce que vous ayez un fichier avec une nouvelle ligne dans son nom.


11
2018-04-02 09:27



.. eh bien, oui, ça - et le fait qu'il commette une demi-douzaine d'infractions flagrantes contre le scripting bash :) - adaptr
Votre lien a été très utile. Merci beaucoup. - B14D3


Oh mon dieu, c'est affreux.

Votre script utilise bash; Je vous suggère de faire ceci à la place:

#!/bin/bash
for i in *.wav; do mv "${i}" "${i%.wav}.ext"; done

Voir le Guide Bash pour plus de détails sur l'expansion des paramètres.


7
2018-04-02 09:25





Vous pouvez essayer ceci.

awk '{print substr($0, index($0,$9))}'

Par exemple, voici le résultat de la commande ls:

-rw-r - r--. 1 racine racine 73834496 6 déc. 10:55 Fichier avec espaces 2

Si vous utilisez un simple awk comme ça

# awk '{print $9}'

Il ne retourne que

# File

Si utilisé avec la commande complète

# awk '{print substr($0, index($0,$9))}'

Je reçois toute la sortie

Fichier avec espaces 2

Ici substr (s, a, b): renvoie le nombre b de caractères de la chaîne s, commençant à la position a. Le paramètre b est optionnel.

Par exemple, si la correspondance est addr: 192.168.1.133 et que vous utilisez substr comme suit

# awk '{print substr($2,6)}'

Vous obtenez l'adresse IP 192.168.1.133. Notez que le 6 est le caractère commençant par un in addr

Ainsi, dans la commande appropriée, $ 2 est égal à 0 (qui affiche la ligne entière.) Et index ($ 0, $ 9) correspond à $ 9 et affiche tout ce qui précède la colonne 9. Vous pouvez le changer en index ($ 0, $ 8) et voir que la sortie change à

# 10:55 File with spaces 2

`index (IN, FIND) '      Cette recherche dans la chaîne IN pour la première occurrence de la chaîne      FIND, et renvoie la position en caractères où cette occurrence      commence dans la chaîne IN.

J'espère que ça aide. De plus, si vous affectez cette valeur à une variable dans un script, vous devez inclure les variables entre guillemets. Sinon, vous obtiendrez des erreurs si vous effectuez une autre opération pour le nom de fichier extrait.


0
2017-12-06 07:01