Dit commando geeft mappen weer in het huidige pad: ls -d */
Wat doet het patroon */
precies?
En hoe kunnen we het absolute pad in het bovenstaande commando geven (bijv. ls -d /home/alice/Documents
) om alleen mappen in dat pad weer te geven?
Antwoord 1, autoriteit 100%
*/
is een patroon dat overeenkomt met alle submappen in de huidige map (*
komt overeen met alle bestanden en submappen; de /
beperkt het tot mappen). Op dezelfde manier, om alle submappen onder /home/alice/Documents weer te geven, gebruik je ls -d /home/alice/Documents/*/
Antwoord 2, autoriteit 47%
Vier manieren om dit voor elkaar te krijgen, elk met een ander uitvoerformaat
1. echo
gebruiken
Voorbeeld: echo */
, echo */*/
Dit is wat ik heb:
cs/ draft/ files/ hacks/ masters/ static/
cs/code/ files/images/ static/images/ static/stylesheets/
2. Alleen ls
gebruiken
Voorbeeld: ls -d */
Dit is precies wat ik heb:
cs/ files/ masters/
draft/ hacks/ static/
Of als lijst (met gedetailleerde info): ls -dl */
3. Gebruik ls
en grep
Voorbeeld: ls -l | grep "^d"
Dit is wat ik heb:
drwxr-xr-x 24 h staff 816 Jun 8 10:55 cs
drwxr-xr-x 6 h staff 204 Jun 8 10:55 draft
drwxr-xr-x 9 h staff 306 Jun 8 10:55 files
drwxr-xr-x 2 h staff 68 Jun 9 13:19 hacks
drwxr-xr-x 6 h staff 204 Jun 8 10:55 masters
drwxr-xr-x 4 h staff 136 Jun 8 10:55 static
4. Bash-script (niet aanbevolen voor bestandsnamen die spaties bevatten)
Voorbeeld: for i in $(ls -d */); do echo ${i%%/}; done
Dit is wat ik heb:
cs
draft
files
hacks
masters
static
Als je ‘/’ als eindteken wilt hebben, is het commando: for i in $(ls -d */); do echo ${i}; done
cs/
draft/
files/
hacks/
masters/
static/
Antwoord 3, autoriteit 10%
Ik gebruik:
ls -d */ | cut -f1 -d'/'
Hiermee wordt een enkele kolom gemaakt zonder een schuine streep aan het einde – handig in scripts.
Antwoord 4, autoriteit 6%
Voor alle mappen zonder submappen:
find /home/alice/Documents -maxdepth 1 -type d
Voor alle mappen met submappen:
find /home/alice/Documents -type d
Antwoord 5, autoriteit 4%
Vier (meer) betrouwbare opties.
Een niet aangehaalde asterisk *
wordt door de shell geïnterpreteerd als een patroon (glob). De shell zal het gebruiken bij padnaamuitbreiding. Het genereert dan een lijst met bestandsnamen die overeenkomen met het patroon.
Een eenvoudig sterretje komt overeen met alle bestandsnamen in de PWD (huidige werkmap). Een complexer patroon als */
komt overeen met alle bestandsnamen die eindigen op /
. Dus alle mappen. Daarom het commando:
1.- echo.
echo */
echo ./*/ ### Avoid misinterpreting filenames like "-e dir"
wordt uitgebreid (door de shell) naar echo
alle mappen in de PWD.
Om dit te testen: maak een map (mkdir
) aan met de naam test-dir, en cd
erin:
mkdir test-dir; cd test-dir
Maak enkele mappen:
mkdir {cs,files,masters,draft,static} # Safe directories.
mkdir {*,-,--,-v\ var,-h,-n,dir\ with\ spaces} # Some a bit less secure.
touch -- 'file with spaces' '-a' '-l' 'filename' # And some files:
Het commando echo ./*/
blijft betrouwbaar, zelfs met oneven benoemde bestanden:
./--/ ./-/ ./*/ ./cs/ ./dir with spaces/ ./draft/ ./files/ ./-h/
./masters/ ./-n/ ./static/ ./-v var/
Maar de spaties in bestandsnamen maken het lezen een beetje verwarrend.
Als in plaats van echo
, gebruiken we ls
. De shell is nog steeds wat de lijst met bestandsnamen uitbreidt. De shell is de reden om een lijst met mappen in de PWD te krijgen. De optie -d
voor ls
zorgt ervoor dat het huidige directory-item wordt weergegeven in plaats van de inhoud van elke directory (zoals standaard weergegeven).
ls -d */
Dit commando is echter (iets) minder betrouwbaar. Het zal mislukken met de oneven benoemde bestanden die hierboven worden vermeld. Het zal stikken met verschillende namen. Je moet één voor één wissen totdat je degene met problemen vindt.
2.- ls
De GNU ls
accepteert de toets “einde van opties” (--
).
ls -d ./*/ ### More reliable BSD ls
ls -d -- */ ### More reliable GNU ls
3.-printf
Om elke directory op zijn eigen regel te vermelden (in één kolom, vergelijkbaar met ls -1), gebruik:
$ printf "%s\n" */ ### Correct even with "-", spaces or newlines.
En, nog beter, we zouden de achterliggende /
kunnen verwijderen:
$ set -- */; printf "%s\n" "${@%/}" ### Correct with spaces and newlines.
Een poging zoals
$ for i in $(ls -d */); do echo ${i%%/}; done
zal mislukken op:
- enkele namen (
ls -d */
) zoals hierboven al getoond. - wordt beïnvloed door de waarde van
IFS
. - zal namen op spaties en tabs splitsen (met standaard
IFS
). - elke nieuwe regel in de naam start een nieuw echo-commando.
4.- Functie
Ten slotte heeft het gebruik van de lijst met argumenten binnen een functie geen invloed op de lijst met argumenten van de huidige actieve shell. Gewoon
$ listdirs(){ set -- */; printf "%s\n" "${@%/}"; }
$ listdirs
presenteert deze lijst:
--
-
*
cs
dir with spaces
draft
files
-h
masters
-n
static
-v var
Deze opties zijn veilig met verschillende soorten oneven bestandsnamen.
Antwoord 6, autoriteit 2%
De opdracht tree
is hier ook erg handig . Standaard toont het alle bestanden en mappen tot een volledige diepte, met enkele ASCII-tekens die de mappenboom tonen.
$ tree
.
+-- config.dat
+-- data
¦ +-- data1.bin
¦ +-- data2.inf
¦ L-- sql
| ¦ L-- data3.sql
+-- images
¦ +-- background.jpg
¦ +-- icon.gif
¦ L-- logo.jpg
+-- program.exe
L-- readme.txt
Maar als we alleen de mappen wilden krijgen, zonder de ASCII-structuur, en met het volledige pad van de huidige map, zou je het volgende kunnen doen:
$ tree -dfi
.
./data
./data/sql
./images
De argumenten zijn:
-d List directories only.
-f Prints the full path prefix for each file.
-i Makes tree not print the indentation lines, useful when used in conjunction with the -f option.
En als u dan het absolute pad wilt, kunt u beginnen met het opgeven van het volledige pad naar de huidige map:
$ tree -dfi "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/data/sql
/home/alice/Documents/images
En om het aantal submappen te beperken, kunt u het maximale niveau van submappen instellen met -L level
, bijvoorbeeld:
$ tree -dfi -L 1 "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/images
Meer argumenten zijn te zien met man tree
.
Antwoord 7, autoriteit 2%
Voor het geval je je afvraagt waarom uitvoer van ‘ls -d */’ je twee slashes geeft, zoals:
[prompt]$ ls -d */
app// cgi-bin// lib// pub//
waarschijnlijk komt dat doordat ergens in uw shell- of sessieconfiguratiebestanden het ls-commando een alias vormt voor een versie van ls die de vlag -F
bevat. Die vlag voegt een teken toe aan elke uitvoernaam (dat is geen gewoon bestand) om aan te geven wat voor soort ding het is. De ene schuine streep komt dus overeen met het patroon ‘*/’ en de andere schuine streep is de toegevoegde type-indicator.
Om van dit probleem af te komen, kunt u natuurlijk een andere alias definiëren voor ls. Om de alias echter tijdelijk niet aan te roepen, kunt u de opdracht toevoegen met een backslash:
\ls -d */
Antwoord 8
Een duidelijke lijst van de huidige map, het zou zijn:
ls -1d */
Als je het gesorteerd en opgeruimd wilt hebben:
ls -1d */ | cut -c 1- | rev | cut -c 2- | rev | sort
Onthoud: tekens met hoofdletters gedragen zich verschillend in de sortering
Antwoord 9
Ik voeg dit gewoon toe aan mijn .bashrc
-bestand (je zou het ook gewoon op de opdrachtregel kunnen typen als je het maar voor één sessie nodig hebt/wilt):
alias lsd='ls -ld */'
Vervolgens zal lsd het gewenste resultaat opleveren.
Antwoord 10
Echte ls
-oplossing, inclusief symbolische links naar mappen
Veel antwoorden hier gebruiken ls
niet (of gebruiken het alleen in de triviale betekenis van ls -d
, terwijl ze jokertekens gebruiken voor de daadwerkelijke subdirectory-overeenkomst. Een true ls
-oplossing is handig, omdat het het gebruik van ls
-opties voor sorteervolgorde, enz. toestaat.
Exclusief symbolische links
Er is één oplossing gegeven die ls
gebruikt, maar deze doet iets anders dan de andere oplossingen doordat het symlinks uitsluit naar mappen:
ls -l | grep '^d'
(eventueel door sed
of awk
geleiden om de bestandsnamen te isoleren)
Inclusief symbolische links
In het (waarschijnlijk vaker voorkomende) geval dat symlinks naar mappen moeten worden opgenomen, kunnen we de optie -p
van ls
gebruiken, waardoor er een schuine streep aan wordt toegevoegd naar namen van mappen (inclusief gelinkte mappen):
ls -1p | grep '/$'
of, het wegwerken van de slashes:
ls -1p | grep '/$' | sed 's/\/$//'
We kunnen indien nodig opties toevoegen aan ls
(als een lange lijst wordt gebruikt, is de -1
niet langer vereist).
Opmerking: als we achterslashes willen, maar niet willen dat ze worden gemarkeerd door grep
, kunnen we de markering hackachtig verwijderen door het daadwerkelijk overeenkomende gedeelte van de regel is leeg:
ls -1p | grep -P '(?=/$)'
Antwoord 11
Als een verborgen map niet hoeft te worden vermeld, bied ik het volgende aan:
ls -l | grep "^d" | awk -F" " '{print $9}'
En als verborgen mappen moeten worden weergegeven, gebruik dan:
ls -Al | grep "^d" | awk -F" " '{print $9}'
Of
find -maxdepth 1 -type d | awk -F"./" '{print $2}'
Antwoord 12
Mappenlijsten weergeven zonder /
:
ls -d */|sed 's|[/]||g'
Antwoord 13
Alleen voor het weergeven van directories:
ls -l | grep ^d
Voor het weergeven van alleen bestanden:
ls -l | grep -v ^d
Of je kunt het ook doen als:
ls -ld */
Antwoord 14
Probeer deze eens. Het werkt voor alle Linux-distributies.
ls -ltr | grep drw
Antwoord 15
Dit is wat ik gebruik
ls -d1 /Directory/Path/*;
Antwoord 16
Test of het item een directory is met test -d
:
for i in $(ls); do test -d $i && echo $i ; done
Antwoord 17
Ter info, als u alle bestanden in meerdere regels wilt afdrukken, kunt u een ls -1
doen die elk bestand op een aparte regel afdrukt.
bestand1
bestand2
bestand3
Antwoord 18
*/
is een patroon dat overeenkomt met een bestandsnaam dat overeenkomt met mappen in de huidige map.
Om alleen mappen weer te geven, vind ik deze functie leuk:
# Long list only directories
llod () {
ls -l --color=always "$@" | grep --color=never '^d'
}
Zet het in uw .bashrc-bestand.
Gebruiksvoorbeelden:
llod # Long listing of all directories in current directory
llod -tr # Same but in chronological order oldest first
llod -d a* # Limit to directories beginning with letter 'a'
llod -d .* # Limit to hidden directories
Opmerking: het gaat kapot als je de optie -i
gebruikt. Hier is een oplossing voor:
# Long list only directories
llod () {
ls -l --color=always "$@" | egrep --color=never '^d|^[[:digit:]]+ d'
}
Antwoord 19
file * | grep directory
Uitvoer (op mijn computer) —
[root@rhel6 ~]# file * | grep directory
mongo-example-master: directory
nostarch: directory
scriptzz: directory
splunk: directory
testdir: directory
De bovenstaande uitvoer kan verder worden verfijnd door cut:
te gebruiken
file * | grep directory | cut -d':' -f1
mongo-example-master
nostarch
scriptzz
splunk
testdir
* could be replaced with any path that's permitted
file - determine file type
grep - searches for string named directory
-d - to specify a field delimiter
-f1 - denotes field 1
Antwoord 20
One-liner om mappen alleen vanaf “hier” weer te geven.
Met aantal bestanden.
for i in `ls -d */`; do g=`find ./$i -type f -print| wc -l`; echo "Directory $i contains $g files."; done
Antwoord 21
Perl gebruiken:
ls | perl -nle 'print if -d;'
Antwoord 22
Ik heb het gedeeltelijk opgelost met:
cd "/path/to/pricipal/folder"
for i in $(ls -d .*/); do sudo ln -s "$PWD"/${i%%/} /home/inukaze/${i%%/}; done
ln: «/home/inukaze/./.»: can't overwrite a directory
ln: «/home/inukaze/../..»: can't overwrite a directory
ln: accesing to «/home/inukaze/.config»: too much symbolics links levels
ln: accesing to «/home/inukaze/.disruptive»: too much symbolics links levels
ln: accesing to «/home/inukaze/innovations»: too much symbolics links levels
ln: accesing to «/home/inukaze/sarl»: too much symbolics links levels
ln: accesing to «/home/inukaze/.e_old»: too much symbolics links levels
ln: accesing to «/home/inukaze/.gnome2_private»: too much symbolics links levels
ln: accesing to «/home/inukaze/.gvfs»: too much symbolics links levels
ln: accesing to «/home/inukaze/.kde»: too much symbolics links levels
ln: accesing to «/home/inukaze/.local»: too much symbolics links levels
ln: accesing to «/home/inukaze/.xVideoServiceThief»: too much symbolics links levels
Nou, dit is voor mij het grootste deel 🙂
Antwoord 23
Toevoegen om het een volledige cirkel te maken, om het pad van elke map op te halen, gebruik een combinatie van het antwoord van Albert en Gordans. Dat zou best handig moeten zijn.
for i in $(ls -d /pathto/parent/folder/*/); do echo ${i%%/}; done
Uitvoer:
/pathto/parent/folder/childfolder1/
/pathto/parent/folder/childfolder2/
/pathto/parent/folder/childfolder3/
/pathto/parent/folder/childfolder4/
/pathto/parent/folder/childfolder5/
/pathto/parent/folder/childfolder6/
/pathto/parent/folder/childfolder7/
/pathto/parent/folder/childfolder8/
Antwoord 24
Hier is een variatie die gebruikmaakt van tree die directorynamen alleen op afzonderlijke regels uitvoert, ja het is lelijk, maar hey, het werkt.
tree -d | grep -E '^[+|L]' | cut -d ' ' -f2
of met awk
tree -d | grep -E '^[+|L]' | awk '{print $2}'
Dit is echter waarschijnlijk beter en behoudt de /
achter de directorynaam.
ls -l | awk '/^d/{print $9}'
Antwoord 25
Om de oorspronkelijke vraag te beantwoorden, */
heeft op zich niets te maken met ls
; het wordt gedaan door de shell/Bash, in een proces dat bekend staat als globbing.
Dit is de reden waarom echo */
en ls -d */
dezelfde elementen uitvoeren. (De vlag -d
zorgt ervoor dat ls
de directorynamen uitvoert en niet de inhoud van de directory’s.)
Antwoord 26
Dit is wat ik gebruik om alleen directorynamen weer te geven:
ls -1d /some/folder/*/ | awk -F "/" "{print \$(NF-1)}"
Antwoord 27
als je ruimte hebt in je mapnaam $9, zal print niet werken, probeer dan onderstaande opdracht
ls -l yourfolder/alldata/ | grep '^d' | awk '{print $9" " $10}'
uitvoer
ls -l yourfolder/alldata/ | grep '^d' | awk '{print $9" " $10}'
testing_Data
Folder 1