Jak usunąć przyrostek pliku i część ścieżki z ciągu ścieżki w Bash?

Podano ścieżkę do pliku typu string, np. " / foo / fizzbuzz.bar", jak użyć Basha, aby wyodrębnić tylko "fizzbuzz" część wspomnianego ciągu?

Author: codeforester, 2008-09-24

13 answers

Oto Jak to zrobić z operatorami # i % w Bash.

$ x="/foo/fizzbuzz.bar"
$ y=${x%.bar}
$ echo ${y##*/}
fizzbuzz

${x%.bar} może być również ${x%.*}, aby usunąć wszystko po kropce lub ${x%%.*}, Aby usunąć wszystko po pierwszej kropce.

Przykład:

$ x="/foo/fizzbuzz.bar.quux"
$ y=${x%.*}
$ echo $y
/foo/fizzbuzz.bar
$ y=${x%%.*}
$ echo $y
/foo/fizzbuzz

Dokumentacja znajduje się w instrukcji Bash. Poszukaj ${parameter%word} i ${parameter%%word} sekcji dopasowującej końcowe porcje.

 448
Author: Zan Lynx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-14 14:36:17

Spójrz na polecenie basename:

NAME=`basename /foo/fizzbuzz.bar .bar`
 177
Author: zigdon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 03:38:03

Czysty bash, wykonywany w dwóch oddzielnych operacjach:

  1. Usuń ścieżkę z łańcucha ścieżek:

    path=/foo/bar/bim/baz/file.gif
    
    file=${path##*/}  
    #$file is now 'file.gif'
    
  2. Usuń rozszerzenie z łańcucha ścieżki:

    base=${file%.*}
    #${base} is now 'file'.
    
 30
Author: Param,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-29 17:48:03

Używając basename, użyłem następujących elementów, aby to osiągnąć:

for file in *; do
    ext=${file##*.}
    fname=`basename $file $ext`

    # Do things with $fname
done;

Nie wymaga to a priori znajomości rozszerzenia pliku i działa nawet wtedy, gdy masz nazwę pliku, która ma kropki w nazwie pliku (przed rozszerzeniem); wymaga to jednak programu basename, ale jest to część GNU coreutils, więc powinien być dostarczany z każdą dystrybucją.

 13
Author: mike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-11 17:07:04

Pure bash way:

~$ x="/foo/bar/fizzbuzz.bar.quux.zoom"; 
~$ y=${x/\/*\//}; 
~$ echo ${y/.*/}; 
fizzbuzz

Ta funkcjonalność jest wyjaśniona w Man bash pod "Parameter Expansion". Nie bash sposoby obfitują: awk, perl, sed i tak dalej.

EDIT: działa z kropkami w pliku przyrostki i nie musi znać przyrostka (rozszerzenia), ale nie działaz kropkami w samej nazwie .

 12
Author: Vinko Vrsalovic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-02 15:59:07

Funkcje basename i dirname są tym, czego szukasz:

mystring=/foo/fizzbuzz.bar
echo basename: $(basename $mystring)
echo basename + remove .bar: $(basename $mystring .bar)
echo dirname: $(dirname $mystring)

MA Wyjście:

basename: fizzbuzz.bar
basename + remove .bar: fizzbuzz
dirname: /foo
 7
Author: Jerub,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 03:40:06
perl -pe 's/\..*$//;s{^.*/}{}'
 3
Author: mopoke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 03:39:34

Użycie basename zakłada, że wiesz, czym jest rozszerzenie pliku, prawda?

I uważam, że różne sugestie wyrażeń regularnych nie radzą sobie z nazwą pliku zawierającą więcej niż jeden "."

Poniższe wydaje się radzić sobie z podwójnymi kropkami. O, i nazwy plików, które zawierają same " / " (just for kicks)

Parafrazując Pascala: "Przepraszam, że ten skrypt jest tak długi. Nie miałem czasu, żeby to skrócić "


  #!/usr/bin/perl
  $fullname = $ARGV[0];
  ($path,$name) = $fullname =~ /^(.*[^\\]\/)*(.*)$/;
  ($basename,$extension) = $name =~ /^(.*)(\.[^.]*)$/;
  print $basename . "\n";
 
 3
Author: Andrew Edgecombe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 05:07:37

Jeśli nie możesz użyć basename, jak sugerowano w innych postach, zawsze możesz użyć sed. Oto (brzydki) przykład. Nie jest najlepszy, ale działa poprzez wyodrębnienie poszukiwanego ciągu i zastąpienie wejścia poszukiwanym ciągiem.

echo '/foo/fizzbuzz.bar' | sed 's|.*\/\([^\.]*\)\(\..*\)$|\1|g'

Który da ci wyjście

Fizzbuzz

 2
Author: nymacro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 11:12:06

Uważaj na sugerowane rozwiązanie Perla: usuwa wszystko po pierwszej kropce.

$ echo some.file.with.dots | perl -pe 's/\..*$//;s{^.*/}{}'
some

Jeśli chcesz to zrobić z perlem, to działa:

$ echo some.file.with.dots | perl -pe 's/(.*)\..*$/$1/;s{^.*/}{}'
some.file.with

Ale jeśli używasz Bash, rozwiązania z y=${x%.*} (lub basename "$x" .ext Jeśli znasz rozszerzenie) są znacznie prostsze.

 2
Author: mivk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-19 10:35:04

Łączenie najwyżej ocenionej odpowiedzi z drugą najwyżej ocenioną odpowiedzią, aby uzyskać nazwę pliku bez pełnej ścieżki:

$ x="/foo/fizzbuzz.bar.quux"
$ y=(`basename ${x%%.*}`)
$ echo $y
fizzbuzz
 1
Author: c.gutierrez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-20 18:30:44

Basename robi to, usuwa ścieżkę. Usunie również przyrostek, jeśli jest podany i jeśli pasuje do przyrostka pliku, ale musisz znać przyrostek, aby podać polecenie. W przeciwnym razie możesz użyć mv i dowiedzieć się, jaka nowa nazwa powinna być w inny sposób.

 0
Author: waynecolvin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-15 00:47:41

Informacje można znaleźć w Instrukcji Bash, poszukaj ${parameter%word} i ${parameter%%word} w sekcji dopasowania końcowych części.

 0
Author: 1ac0,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-20 11:44:53