Витягнути ім'я файлу з шляху в програмі awk


21

У мене є awk-скрипт, і я передав файл CSV до нього.

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

Що я роблю, це отримати FILENAME всередині script.awk. FILENAME дає мені весь шлях. Оскільки я в розпуці, я не можу використовувати basename FILENAME.

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

Я намагався з цим всередині script.awk

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

але я не можу виконати це всередині script.awk. Як я можу потрапити asgd.csvв програму awk?

Відповіді:


33

Кілька варіантів:

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

Або:

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

Зауважте, що такі реалізації файлів basenameповинні працювати для загальних випадків, але не в кутових випадках, наприклад, basename /path/to/x///коли вони повертають порожню рядок замість xабо /де вони повертають порожню рядок замість /, хоча для звичайних файлів, цього не повинно відбуватися.

Перший не буде працювати належним чином, якщо шляхи до файлів (до останнього /) містять послідовності байтів, які не утворюють дійсних символів у поточній локалі (зазвичай така річ трапляється в локаціях UTF-8 з назви файлів, закодованими в деяких 8 набір символів однобітових біт). Ви можете обійти це, встановивши локаль на C, де кожна послідовність байтів утворює дійсні символи.


5
Якщо вам потрібен код , який буде працювати легко в межах існуючого AWK сценарію без введення функції, ви повинні використовувати: n = split(FILENAME, a, "/"); basename=a[n];. Не використовуйте, subоскільки це фактично змінить FILENAMEзмінну (що не стосується функції, оскільки awk використовує виклик за значенням).
ширі

10

Спробуйте цей однокласний лайнер,

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

3
абоawk 'END{ var=FILENAME; n=split (var,a,/\//); print a[n]}' /home/abc/imp/asgd.csv
Avinash Raj

0

найкращий спосіб експортувати його з вхідного CSV або безпосередньо з вхідного файлу до контуру ви можете змінити його назад, потім отримати 1 стовпець і знову повернути його назад.

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

або просто

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

0

Використовуйте функцію розділення Awk

Один із способів зробити це - використовувати функцію розділення. Наприклад:

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

Це працює навіть у кількох файлах. Наприклад:

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

0

В системах , де basenameкоманда доступна, можна використовувати awk«s system()функцію або expression | getline varструктуру для виклику зовнішньої basenameкоманди. Це може допомогти обліку кутових випадків, зазначених у відповіді Стефана .

$ awk '{cmd=sprintf("basename %s",FILENAME);cmd | getline out; print FILENAME,out; exit}' /etc///passwd
/etc///passwd passwd
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.