LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 05-27-2023, 11:50 AM   #1
mackowiakp
Member
 
Registered: Jun 2014
Location: Poland/Gdynia
Distribution: Mageia 9, SH4, Debian
Posts: 367

Rep: Reputation: 8
for i in a b c d


I have in a file called "files" a listing of directories named - let's say - a, b, c, d, e, f etc. Each name is one line.
I would like to write a script in bash that will perform the following functions:

Code:
#!/bin/bash

ls -d -1 */|sed 's/\///' > files

for i in a c g
do
  # do something with $i
done

for i in <all others>
do
  # do something with any else $i
done
Can someone give me a hint how to do that?
 
Old 05-27-2023, 02:22 PM   #2
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,140
Blog Entries: 6

Rep: Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828
Example:
Do something with lines 3 and 5
Something else with line 7
Something else with the rest.

Code:
n=1
while read line; do 
    if [ $n -eq 3 ] || [ $n -eq 5 ]; then
        echo "Do process A with line:"$n" "$line""
    elif [ $n -eq 7 ]; then
        echo "Do process B with line:"$n" "$line""
    else
        echo "Do process C with line:"$n" "$line""
    fi
    n=$((n + 1))
done < files
 
Old 05-27-2023, 02:50 PM   #3
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,140
Blog Entries: 6

Rep: Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828
Or slice up an array
Code:
lines=($(cat files))

#First line
echo "${lines[0]}"

#Line 3-5
echo "${lines[@]:2:3}"

#Last 3
echo ${lines[@]: -3}

#2nd from last
echo ${lines[-2]}
Etc.
 
Old 05-27-2023, 07:45 PM   #4
mackowiakp
Member
 
Registered: Jun 2014
Location: Poland/Gdynia
Distribution: Mageia 9, SH4, Debian
Posts: 367

Original Poster
Rep: Reputation: 8
Quote:
Do something with lines 3 and 5
Something else with line 7
Something else with the rest.
Its OK if You know numbers of the lines.
My problem is that I only know the subdirs names.
I have to do one thing with subdirs whose name does not change and another with other directories, which can be a different number and different names each time.
 
Old 05-27-2023, 09:23 PM   #5
rkelsen
Senior Member
 
Registered: Sep 2004
Distribution: slackware
Posts: 4,457
Blog Entries: 7

Rep: Reputation: 2560Reputation: 2560Reputation: 2560Reputation: 2560Reputation: 2560Reputation: 2560Reputation: 2560Reputation: 2560Reputation: 2560Reputation: 2560Reputation: 2560
Is this a homework question?

Code:
#!/bin/bash

ls -d -1 */|sed 's/\///' > files

for i in `cat files` 
do 
    if [ $i = "a" ] || [ $i = "c" ] || [ $i = "g" ]; then
        echo "Hey I found $i"; else
        echo "You can ignore $i" 
    fi
done
Does that help?
 
1 members found this post helpful.
Old 05-28-2023, 12:56 AM   #6
mackowiakp
Member
 
Registered: Jun 2014
Location: Poland/Gdynia
Distribution: Mageia 9, SH4, Debian
Posts: 367

Original Poster
Rep: Reputation: 8
Quote:
Is this a homework question?
No ;-) But many thanks!
 
Old 05-28-2023, 03:22 AM   #7
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,803

Rep: Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202
$( ) and ` ` produce an argument list that is split at whitespace including embedded spaces, and also by default do "filename generation".
A while-read loop can safely read lines from a text file:
Code:
while IFS= read -r fn
do
  case "$fn" in
  ( "a" | "c" | "g" )
    echo do something with "$fn"
  ;;
  ( * )
    echo do someth else with "$fn"
  ;;
  esac
done < file

Last edited by MadeInGermany; 05-28-2023 at 12:53 PM.
 
1 members found this post helpful.
Old 05-28-2023, 10:44 AM   #8
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,888

Rep: Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317
how do you know a directory belongs to the first group (or the second)?
 
Old 05-28-2023, 05:32 PM   #9
mackowiakp
Member
 
Registered: Jun 2014
Location: Poland/Gdynia
Distribution: Mageia 9, SH4, Debian
Posts: 367

Original Poster
Rep: Reputation: 8
Quote:
how do you know a directory belongs to the first group (or the second)?
I know from this that the names of the first group of directories do not change and are called e.g. a, c, g etc.
The rest of the directories can take different names.
 
Old 05-30-2023, 12:33 AM   #10
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,888

Rep: Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317
Quote:
Originally Posted by mackowiakp View Post
I know from this that the names of the first group of directories do not change and are called e.g. a, c, g etc.
The rest of the directories can take different names.
Ok, so you have some reserved names. I would make a list for them, an associative array like this:
Code:
R_DIRS[a]=1
R_DIRS[c]=1
....
for i in "${R_DIRS[@]}"
   do something with the reserved names
done
for i in <all dirs>
    [[ "${R_DIRS[$i]:-0}" -eq 1 ]] && continue
    do something with the others
done
 
1 members found this post helpful.
Old 05-30-2023, 03:53 AM   #11
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,803

Rep: Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202
The associative array with index-only:
Code:
R_DIRS["a"]=
R_DIRS["c"]=
....
for d in "${!R_DIRS[@]}"
do
   echo do something with "$d"
done
for d in <all dirs>
do
    [[ ${R_DIRS[$d]+exist} ]] && continue
    echo something else with "$d"
done
bash 4.2+ supports
Code:
    [[ -v R_DIRS[$d] ]] && continue

Last edited by MadeInGermany; 05-30-2023 at 12:43 PM.
 
1 members found this post helpful.
Old 05-30-2023, 04:31 AM   #12
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,803

Rep: Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202Reputation: 1202
Another idea: extglob
(untested)
Code:
#!/bin/bash
shopt -s extglob nullglob
dirpat="a|c|g"
for d in @($dirpat)/
do
  echo do sth with "$d"
done
for d in !($dirpat)/
do
  echo do sth else with "$d"
done
 
1 members found this post helpful.
  


Reply

Tags
bash, for loop



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 09:33 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration