web-dev-qa-db-fra.com

Extraire le nom de fichier du chemin dans le programme awk

J'ai un script awk et je lui ai passé un fichier CSV.

awk -f script.awk /home/abc/imp/asgd.csv

Qu'est-ce que je fais est d'obtenir FILENAME dans script.awk. FILENAME me donne tout le chemin. Comme je suis dans awk, je ne peux pas utiliser basename FILENAME.

print FILENAME;
/home/abc/imp/asgd.csv

J'ai essayé avec ceci dans script.awk

echo $FILENAME | awk -F"/" '{print $NF}'

mais je ne peux pas l'exécuter dans script.awk. Comment puis-je avoir asgd.csv dans un programme awk?

22
Aashu

Plusieurs options:

awk '
  function basename(file) {
    sub(".*/", "", file)
    return file
  }
  {print FILENAME, basename(FILENAME)}' /path/to/file

Ou:

awk '
  function basename(file, a, n) {
    n = split(file, a, "/")
    return a[n]
  }
  {print FILENAME, basename(FILENAME)}' /path/to/file

Notez que ces implémentations de basename devraient fonctionner pour les cas courants, mais pas dans les cas d'angle comme basename /path/to/x/// où ils renvoient la chaîne vide au lieu de x ou / où ils renvoient la chaîne vide au lieu de /, mais pour les fichiers normaux, cela ne devrait pas se produire.

Le premier ne fonctionnera pas correctement si les chemins d'accès aux fichiers (jusqu'au dernier /) contiennent des séquences d'octets qui ne forment pas de caractères valides dans les paramètres régionaux actuels (généralement ce genre de chose se produit dans les paramètres régionaux UTF-8 avec des noms de fichiers codés dans un jeu de caractères codé sur 8 bits). Vous pouvez contourner cela en fixant les paramètres régionaux à C où chaque séquence d'octets forme des caractères valides.

33

Essayez cet awk one-liner,

$ awk 'END{ var=FILENAME; split (var,a,/\//); print a[5]}' /home/abc/imp/asgd.csv
asgd.csv
10
Avinash Raj

Sur les systèmes où la commande basename est disponible, on pourrait utiliser la fonction system() de awk ou expression | getline var structure pour appeler la commande externe basename. Cela peut aider à rendre compte des cas d'angle mentionnés dans réponse de Stéphane .

$ awk '{cmd=sprintf("basename %s",FILENAME);cmd | getline out; print FILENAME,out; exit}' /etc///passwd
/etc///passwd passwd
2
Sergiy Kolodyazhnyy

la meilleure façon de l'exporter à partir du CSV d'entrée ou directement à partir du chemin du fichier d'entrée, vous pouvez l'inverser, puis obtenir 1 colonne, puis l'inverser à nouveau.

function getFileFromPath() {
    FileName=$1
    cat $FileName | while read Filename
    do
        echo $Filename| rev | awk -v FS='/' '{print $1}' | rev 
    done
}

ou simplement

echo $FileNamePath| rev | awk -v FS='/' '{print $1}' | rev 
0
FariZ

Utilisez la fonction Split d'Awk

Pour ce faire, vous pouvez utiliser la fonction de partage. Par exemple:

awk '{idx = split(FILENAME, parts, "/"); print parts[idx]; nextfile}' /path/to/file

Cela fonctionne même sur plusieurs fichiers. Par exemple:

$ awk '{idx = split(FILENAME, parts, "/"); print parts[idx]; nextfile}' \
      /etc/passwd /etc/group
passwd
group
0
CodeGnome