Cut uma string- Catch: Existe um arquivo com o mesmo nome da string no mesmo caminho

4

Entrada

/in/archive/ABC/20140111_ABC_018_PART_001.dat

Saída desejada:

20140111_ABC_018_PART_001.dat

Comando usado:

cut -d/ -f4 "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat"

Problema:

Na verdade, ele está abrindo o arquivo 20140111_ABC_018_SALESDOC_ITEM_018.dat no caminho /1a/ftproot/archive/ABC/ e exibindo o resultado do arquivo.

    
por Rakesh K 14.01.2014 / 10:44

2 respostas

4

Aqui estão algumas opções:

  1. basename como sugerido por Stephane

    $ basename /1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat
    20140111_PR1_018_SALESDOC_ITEM_001.dat
    

    basename faz parte de coreutils e simplesmente retira o caminho dos nomes dos arquivos.

  2. awk

    $ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat" | 
       awk -F'/' '{print $NF}'
    

    A opção -F para awk define o separador de campo. Então, definimos isso como / e depois imprimimos o último campo ( $NF ).

  3. cut

    $ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat" |  
       cut -d '/' -f 6
    

    -d é o separador de campo e -f 6 informa cut para imprimir apenas o quinto campo.

    Esta é uma abordagem muito limitada, uma vez que requer que você saiba o número de campos com antecedência. Uma maneira melhor seria usar rev (que inverte sua entrada) para fazer o último campo primeiro, depois cut para obter o primeiro campo e então rev para recuperá-lo do jeito que estava:

    $ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat\n" | 
       rev | cut -d/ -f1 | rev
    
  4. Perl

    $ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat\n" |
       perl -pe 's/.+?([^\/]+)$/$1/;'
    

    O -p sinalizador diz perl para imprimir cada linha de entrada depois de executar qualquer script que seja dado como -e . Nesse caso, simplesmente informamos perl para substituir tudo até o trecho mais longo de caracteres que não são / . Como esse é o Perl, existem várias maneiras de fazer isso:

    $ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat\n" | 
       perl -F/ -ane 'print $F[$#F]'
    

    O sinalizador -a informa perl a se comportar como awk , ele dividirá automaticamente cada linha de entrada na matriz @F . Por isso, definimos o delimitador de campo como / com -F e depois imprimimos o último elemento da matriz ($F[$#F] ). O -n faz com que perl faça um loop sobre sua linha de entrada por linha.

  5. grep

    $ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat" | 
      grep -Po '[^/]+$'
    

    O -P ativa os PCREs e o -o significa "imprima apenas a string correspondente". Então, dizemos a grep para procurar a string mais longa de não- / até o final da string de entrada ( $ ).

  6. shell

    $ foo="/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat";     
    $ printf "${foo##*/}\n" 
    

    Isso tira proveito das habilidades de manipulação de strings do shell. Especificamente, a construção ${var##pattern} excluirá a correspondência mais longa de pattern da frente de $var . Então, ##*/ significa apagar tudo até o último / .

  7. sed

    $ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat\n" | 
       sed 's/.*\///'
    

    sed substituirá tudo até o último / .

por 14.01.2014 / 13:09
2

Você deve echo a string em cut :

echo "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat" | cut -d/ -f6

(note que o campo # é 6)

Mas o comentário de Stephane usando basename é a melhor maneira de fazer isso.

    
por 14.01.2014 / 10:47

Tags