cum să scrieți foreach într-o singură linie în csh? (Programare, Shell, Foreach, Csh)

Chan Kim a intrebat.

Uneori folosesc aceeași operațiune foreach cu fișiere țintă diferite în csh.
Dacă pot da comanda foreach într-o singură linie, aș putea înlocui cu ușurință numele fișierelor țintă pentru a repeta procesul (de obicei folosesc `find . -name …` pentru fișierele țintă).
În scopul acestei întrebări, să presupunem că vreau să prind toate fișierele *.txt.

$ foreach i (*.txt)
foreach? cat $i
foreach? end

Am citit https://unix.stackexchange.com/questions/32873/running-a-full-foreach-command și am încercat

alias disp 'echo "foreach i (*.txt)"; echo "cat "$"i"; echo "end"; | /bin/csh'

când scriu disp îmi dă Invalid null command.
Dacă aș putea face asta într-o singură linie, aș putea face !foreach:gs/.c>/.h/ (să fac același lucru înlocuind .c cu .h).Cum pot face asta?

5 răspunsuri
Jonathan Gratus

Această metodă funcționează pentru mine:

printf 'foreach f ( 1 2 3 )
 echo $f 
 end' | tcsh

Comentarii

  • Wow, Aceasta a fost o întrebare lungă fără răspuns, dar răspunsul tău o face! Mulțumesc! –  > Por Chan Kim.
  • ar trebui să fie o linie de alimentare la sfârșit. printf 'foreach f ( 1 2 3 )
    echo $f
    end
    ' | tcsh
    –  > Por umilință.
  • Există vreun avantaj al printf față de doar echo? –  > Por Kevin.
TerrenceSun

Nu există o modalitate ușoară de a face foreach într-o singură linie sub tcsh.

Cu toate acestea, prin utilizarea aliasului, puteți obține ceva foarte apropiat de întrebarea dumneavoastră.

alias disp 'foreach i (*.txt)
  cat $i
end'

Puteți apela disp în terminalul dvs.

Dacă doriți să direcționați rezultatul într-o țeavă, atunci echo `disp` | grep foobar.

Uneori, trebuie să salvăm mai întâi rezultatul, înainte de a continua procesarea: set foo=`disp`

Comentarii

  • Îmi place mai mult acest răspuns decât cel care implică lansarea unui shell copil. Cel mai frecvent motiv pentru a dori să o faceți într-o singură linie este pentru a o folosi ca alias, iar acest lucru îl rezolvă. –  > Por Toată furia.
  • Un dezavantaj al acestei abordări este că istoricul este încurcat. Arată astfel: disp
    cat $i
    end
    –  > Por Toată furia.
Kir Chou

Pentru prima întrebare, nu știu cum să scriu acest lucru direct în fișierul .cshrc.

Dar voi folosi o altă modalitate flexibilă de a face acest lucru.

1: Scrieți un script shell: /home/user/disp.sh (sau orice cale doriți)

#/bin/bash
for line in `find . -name "*.c"`; do
echo ""
   cat "$line"
done

Sau aveți doar shell csh:

#/bin/csh
foreach i (*.c)
    echo $i
end
  1. Adăugați o nouă comandă alias la .cshrc fișier

    alias disp /home/user/disp.sh

  2. 2. Reintroduceți csh shell (sau relogin)

    csh


Pentru a doua întrebare, am făcut-o pe același script disp.sh

Acest exemplu este scris în scriptul bash shell.

#/bin/bash
usage() { echo "Usage: $0 [-d <depth>] [-e <extension>]" 1>&2; exit 1; }
while getopts ":d:e:" o; do
    case "${o}" in
        d)
            d=${OPTARG}
            ;;
        e)
            e=${OPTARG}
            ;;
        *)
            usage
            ;;
    esac
done
shift $((OPTIND-1))
if [ -z "${d}" ] || [ -z "${e}" ]; then
    usage
fi

for line in `find . -maxdepth ${d} -name "*.${e}"`; do
echo ""
   cat "$line"
done

Puteți tasta pur și simplu disp -d 1 -e c pentru a găsi toate fișierele .c din calea curentă. (-d înseamnă adâncimea fișierului care este pornit din calea curentă, -e înseamnă extensia fișierelor)

Comentarii

  • Bună, cred că nu ați înțeles bine întrebarea. Am vrut să folosesc întreaga comandă foreach într-o singură linie, astfel încât să pot înlocui o parte din ea și să pot rula comanda din nou cu ușurință. În bash, pot face pur și simplu for i in 1 2 3; do echo $i; done . –  > Por Chan Kim.
Joonho Park

Am încercat să găsesc răspunsul, dar se pare că nu există nici o cale. Folosiți doar bash prin simpla schimbare de shell.

% bash

$ for f in *txt; do echo $f; done

$ exit

%

Paul Lippens

Utilizați bash -c:

$ bash -c ‘for i in *.txt; do cat $i; done’